package com.example.ephuizi.stl.util.point_light;

import android.content.Context;
import android.opengl.GLES20;
import android.opengl.GLSurfaceView;
import android.opengl.Matrix;
import android.util.FloatMath;
import android.util.Log;
import android.view.MotionEvent;

import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;

public class MySurfaceView extends GLSurfaceView {

    private static final String TAG = MySurfaceView.class.getSimpleName();
    private static final float TOUCH_SCALE_FACTOR = 180.0f / 320;
    private static final int DRAG = 0X10;
    private static final int ZOOM = 0X20;
    private static final int ROTATION = 0X30;
    private static final int NONE = 0X40;

    private float mDensity;
    private String stlPath;

    private final MyGLRenderer mRenderer;

    public MySurfaceView(Context context, float mDensity, String stlPath) {
        super(context);

        // Create an OpenGL ES 2.0 context
        setEGLContextClientVersion(2);

        this.mDensity = mDensity;
        this.stlPath = stlPath;

        mRenderer = new MyGLRenderer();

        // Set the Renderer for drawing on the GLSurfaceView
        setRenderer(mRenderer);

        // Render the view only when there is a change in the drawing data
        setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);

    }


    private float mPreviousX;
    private float mPreviousY;

    private float mFirstX = -1;
    private float mFirstY = -1;
    private float mSecondX = -1;
    private float mSecondY = -1;
    private int mode = NONE;

    @Override
    public boolean onTouchEvent(MotionEvent event) {


        float x = event.getX();
        float y = event.getY();

        switch (event.getAction() & MotionEvent.ACTION_MASK) {
            case MotionEvent.ACTION_DOWN:
                //设置rotation模式
                mFirstX = event.getX();
                mFirstY = event.getY();
                Log.d(TAG, "mode=ROTATION");
                mode = ROTATION;

                break;
            case MotionEvent.ACTION_UP:
            case MotionEvent.ACTION_POINTER_UP:
                mode = NONE;
                Log.e(TAG, "mode=NONE");
                break;

            case MotionEvent.ACTION_POINTER_DOWN:
                mFirstX = event.getX(0);
                mFirstY = event.getY(0);
                mSecondX = event.getX(1);
                mSecondY = event.getY(1);

                break;

            case MotionEvent.ACTION_MOVE:
                //多点触摸模式
                if (mode != NONE && event.getPointerCount() > 1) {
                    float fFirstX = event.getX(0);
                    float fFirstY = event.getY(0);
                    float fSecondX = event.getX(1);
                    float fSecondY = event.getY(1);

                    //手势方向的向量夹角.
                    float gestureAngle = calculateAngle(mFirstX, mFirstY, fFirstX, fFirstY, mSecondX, mSecondY, fSecondX, fSecondY);
                    if (gestureAngle * 2 > 3.14) {
                        mode = ZOOM;
                    } else {
                        // <60度 ,为DRAG模式
                        mode = DRAG;
                    }
                }

                if (mode == ROTATION) {
                    if (mRenderer != null) {
                        float deltaX = (x - mPreviousX) / mDensity / 2f;
                        float deltaY = (y - mPreviousY) / mDensity / 2f;

                        mRenderer.getObjF().setmDeltaX(mRenderer.getObjF().getmDeltaX() + deltaX);
                        mRenderer.getObjF().setmDeltaY(mRenderer.getObjF().getmDeltaY() + deltaY);
                    }

                    float dx = x - mPreviousX;
                    float dy = y - mPreviousY;

                    requestRender();

                }
                //若为ZOOM模式，则多点触摸缩放
                else if (mode == ZOOM) {
                    float newDist = spacing(event);
                    Log.e(TAG, "newDist=" + newDist);
                    if (newDist > 10f) {

                    }
                    requestRender();
                }
                //若为DRAG模式，则平移
                else if (mode == DRAG) {
                    Log.e(TAG, "mode=DRAG");

                    Log.e(TAG, " mfx : " + mFirstX + " mfy : " + mFirstX + " fSx : " + mSecondX + " fSy : " + mSecondY);
                    Log.e(TAG, " mSx : " + event.getX(0) + " mSy : " + event.getY(0) + " fSx : " + event.getX(1) + " fSy : " + event.getX(1));
//                    float deltaX = (x - mPreviousX) / mDensity / 2f;
//                    float deltaY = (y - mPreviousY) / mDensity / 2f;
//
//                    mRenderer.getObjF().setTranslateX(mRenderer.getObjF().getTranslateX() + deltaX);
//                    mRenderer.getObjF().setTranslateY(mRenderer.getObjF().getTranslateY() + deltaY);
//                    requestRender();
                }
                break;
        }

        mPreviousX = x;
        mPreviousY = y;
        return true; // indicate event was handled
    }

    //计算移动距离
    private float spacing(MotionEvent event) {
        float x = event.getX(0) - event.getX(1);
        float y = event.getY(0) - event.getY(1);
        return FloatMath.sqrt(x * x + y * y);
    }

    private double getLength(float x1, float y1, float x2, float y2) {
        return Math.sqrt(Math.pow(x1 - x2, 2) + Math.pow(y1 - y2, 2));
    }

    /**
     * [bx1,by1,ex1, ey1]与[bx2,by2,ex2, ey2]的夹角
     *
     * @param bX1
     * @param bY1
     * @param eX1
     * @param eY1
     * @param bX2
     * @param bY2
     * @param eX2
     * @param eY2
     * @return
     */
    private float calculateAngle(float bX1, float bY1, float eX1, float eY1, float bX2, float bY2, float eX2, float eY2) {
        //cos(angle) = dotProduct/(norm1*norm12);
        double dotProduct = (eX1 - bX1) * (eX2 - bX2) + (eY1 - bY1) * (eY2 - bY2);
        double norm1 = bX1 * eY1 - bY1 * eX1;
        double norm12 = bX2 * eY2 - bY2 * eX2;
        double angle = Math.acos(dotProduct / (norm1 * norm12));
        return (float) angle;
    }

    /**
     * Created by ephuizi@gmail.com on 2015/7/28.
     */
    public class MyGLRenderer implements GLSurfaceView.Renderer {
        private GLObjectForDraw objF;

        public void onSurfaceCreated(GL10 unused, EGLConfig config) {
            // Set the background frame color
            //设置屏幕背景色RGBA
            GLES20.glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
            //关闭背面剪裁
            GLES20.glDisable(GLES20.GL_CULL_FACE);
            //打开深度检测
            GLES20.glEnable(GLES20.GL_DEPTH_TEST);
            //初始化变换矩阵
            objF = new GLObjectForDraw(MySurfaceView.this, stlPath);//创建角色
        }

        public void onDrawFrame(GL10 unused) {
            // Draw triangle
            objF.draw();
        }

        public void onSurfaceChanged(GL10 unused, int width, int height) {
            // Set the OpenGL viewport to the same size as the surface.
            GLES20.glViewport(0, 0, width, height);

            // Create a new perspective projection matrix. The height will stay the same
            // while the width will vary as per aspect ratio.
            final float ratio = (float) width / height;
            final float left = -ratio;
            final float right = ratio;
            final float bottom = -1.0f;
            final float top = 1.0f;
            final float near = 1.0f;
            final float far = 1000.0f;

            Matrix.frustumM(objF.getmProjectionMatrix(), 0, left, right, bottom, top, near, far);
        }

        public GLObjectForDraw getObjF() {
            return objF;
        }
    }
}